<%@Page Language="VB"%>
<%@Import Namespace="System.Data" %>
<%@Import Namespace="System.Xml" %>
<%@Import Namespace="System.Xml.Xpath" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head>
<title>Synchronization of the XMLDataDocument and DataSet objects</title>
<!-- #include file="..\global\style.inc" -->
</head>
<body bgcolor="#ffffff">
<span class="heading">Synchronization of the XMLDataDocument and DataSet objects</span><hr />
<!--------------------------------------------------------------------------->

<div id="outDocURL" runat="server"></div><p />

<b>List of authors found using the DOM</b>:<br/>
<div id="outDOMResult" runat="server"></div><p />

<b>List of authors found with an XPathNavigator</b>:<br/>
<div id="outXPNavResult" runat="server"></div><p />

<b>Contents of DataSet.Tables(0)</b>:<br/>
<asp:datagrid id="dgrResult" runat="server" /><p />

<b>XML from DataSet extracted with GetElementFromRow</b>:<br/>
<div id="outFromRowResult" runat="server"></div><p />

<div id="outError" runat="server"></div>

<script language="vb" runat="server">

Sub Page_Load()

   'create physical path to booklist sample files (in same folder as ASPX page)
   Dim strCurrentPath As String = Request.PhysicalPath
   Dim strXMLPath As String = Left(strCurrentPath, InStrRev(strCurrentPath, "\")) & "booklist-dataset.xml"
   Dim strSchemaPath As String = Left(strCurrentPath, InStrRev(strCurrentPath, "\")) & "booklist-schema.xsd"

   'create a new XMLDataDocument object
   Dim objXMLDataDoc As New XMLDataDocument()

   Try

      'load the XML schema into the XMLDataDocument object
      objXMLDataDoc.DataSet.ReadXmlSchema(strSchemaPath)
      outDocURL.innerHTML = "Loaded file: <b><a href=""" & strSchemaPath _
                          & """>" & strSchemaPath & "</a></b><br />"

      'load the XML file into the XMLDataDocument object
      objXMLDataDoc.Load(strXMLPath)
      outDocURL.innerHTML += "Loaded file: <b><a href=""" & strXMLPath _
                          & """>" & strXMLPath & "</a></b><br />"

   Catch objError As Exception

      'display error details
      outError.innerHTML = "<b>* Error while accessing document</b>.<br />" _
          & objError.Message & "<br />" & objError.Source
      Exit Sub  ' and stop execution

   End Try

   'now ready to use the XMLDataDocument object

   '*************************************************************
   '*** 1: Extract the author names using the XML DOM methods ***
   '*************************************************************

   Dim objNode As XmlNode
   Dim strResults As String = ""

   'create a NodeList collection of all matching child nodes
   Dim colElements As XmlNodeList
   colElements = objXMLDataDoc.GetElementsByTagname("LastName")

   Dim Dummy As Integer = colElements.Count  '**********************<<<<<<<< error if removed

   'iterate through the collection getting the values of the
   'child #text nodes for each one
   For Each objNode In colElements
     strResults += objNode.FirstChild().Value & " &nbsp; "
   Next

   'then display the result
   outDOMResult.innerHTML = strResults
   strResults = ""

   '*****************************************************************
   '*** 2: extract the author names with an XPathNavigator object ***
   '*****************************************************************

   'create a new XPathNavigator object using the XMLDataDocument object
   Dim objXPNav As XPathNavigator
   objXPNav = objXMLDataDoc.CreateNavigator()

   'move to the root element of the document
   objXPNav.MoveToRoot()

   'and display the result of the recursive 'search' function
   outXPNavResult.innerHTML = SearchForElement(objXPNav, "LastName")

   '***************************************************************************
   '*** 3: Display content of the XMLDataDocument object's DataSet property ***
   '***************************************************************************

   'create a DataView object for the Books table in the DataSet
   Dim objDataView As New DataView(objXMLDataDoc.DataSet.Tables(0))

   'assign the DataView object to the DataGrid control
   dgrResult.DataSource = objDataView
   dgrResult.DataBind()  'and bind (display) the data

   '*************************************************************************
   '*** 4: Extract XML elements from the XMLDataDocument object's DataSet ***
   '*************************************************************************

   'create a DataTable object for the Books table in the DataSet
   Dim objDataTable As DataTable = objXMLDataDoc.DataSet.Tables(0)

   Dim objRow As DataRow
   Dim objXMLElement As XmlElement

   'iterate through all the rows in this table
   For Each objRow In objDataTable.Rows

      'get an XML element that represents this row
      objXMLElement = objXMLDataDoc.GetElementFromRow(objRow)

      'HTMLEncode it because it contains XML element tags
      strResults += Server.HtmlEncode(objXMLElement.OuterXML) & "<br />"

   Next

   'display the result
   outFromRowResult.innerHTML = strResults

   '*************************************************************************

End Sub


'recursive function used by step 2 - using an XPathNavigator
Function SearchForElement(objXPNav As XPathNavigator, _
                          strNodeName As String) As String

   Dim strResults As String = ""    'to hold the result

   Do 'start a 'repeat-until' loop

      'see if this node is an element that we're looking for
      If objXPNav.Name = strNodeName Then

         'move to the the first child (i.e the #text) node
         objXPNav.MoveToFirstChild()

         'get the value and add to the 'results' string
         strResults += objXPNav.Value & " &nbsp; "

         'move back to the parent of this node (i.e. the element node)
         objXPNav.MoveToParent()

      End If

      'now check of the current node has any child nodes
      If objXPNav.HasChildren Then

         'move to the the first child node
         objXPNav.MoveToFirstChild()

         'recursively call this same function to search the child nodes
         strResults += SearchForElement(objXPNav, strNodeName)

         'move back to the parent of this node
         objXPNav.MoveToParent()

      End If

   'then move to next sibling of current node (if any)
   Loop While objXPNav.MoveToNext()

   Return strResults  'return the result

End Function

</script>

<!--------------------------------------------------------------------------->
<!-- #include file="..\global\foot.inc" -->
</body>
</html>
